package com.kylin.common.paginate;

import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;

import com.kylin.common.exception.BusinessException;
import com.kylin.hibernate.BaseHibernateDAO;
import com.kylin.hibernate.CriteriaInfo;
import com.kylin.hibernate.HibernateSessionFactory;
import com.kylin.hibernate.PropertyCondition;
import com.kylin.hibernate.QueryInfo;
import com.kylin.module.user.orm.User;

public class PageManager {
	protected static Logger log = Logger.getLogger(PageManager.class);

	private static Session hibernateSession = HibernateSessionFactory.getSession();

	public static DisplayPage getDisplayPage(int pageSize, int pageNumber, Criteria criteria) {
		DisplayPage page = new DisplayPage(pageSize, pageNumber);
		int totalCount = ((Integer) criteria.setProjection(Projections.rowCount())
				.uniqueResult()).intValue();
		page.setFullListSize(totalCount);
		int allpage = totalCount/pageSize;
		if(totalCount%pageSize != 0)
			allpage ++;
		if(allpage < pageNumber)
			page.setPageNumber(allpage);
		int startRow = (page.getPageNumber() - 1) * page.getObjectsPerPage();
		List list = criteria.setFirstResult(startRow)
		                 .setMaxResults(page.getObjectsPerPage()).list();
		page.setList(list);
		return page;
	}

	public static DisplayPage getDisplayPage(int pageSize, int pageNumber, CriteriaInfo cinfo) throws BusinessException {
		log.debug("DisplayPage CriteriaInfo=" + cinfo);
		DisplayPage page = new DisplayPage(pageSize, pageNumber);
		Criteria countCriteria = BaseHibernateDAO.getCriteriaFromInfo(cinfo);
		int totalCount = ((Integer) countCriteria.setProjection(Projections.rowCount())
				.uniqueResult()).intValue();
		page.setFullListSize(totalCount);
		int allpage = totalCount/pageSize;
		if(totalCount%pageSize != 0)
			allpage ++;
		if(allpage < pageNumber)
			page.setPageNumber(allpage);
		int startRow = (page.getPageNumber() - 1) * page.getObjectsPerPage();
		Criteria criteria = BaseHibernateDAO.getCriteriaFromInfo(cinfo);
		List list = criteria.setFirstResult(startRow)
		                 .setMaxResults(page.getObjectsPerPage()).list();
		page.setList(list);
		page.setSearchId( ""+cinfo.hashCode() );
		log.debug("page.list.size=" + list.size());
		log.debug("page.searchId=" + page.getSearchId());
		return page;
	}

	public static DisplayPage getDisplayPage(int pageSize, int pageNumber, QueryInfo queryInfo) {
		log.debug("\n*******\n* queryInfo.getQueryString=" + queryInfo.getQueryString());
		Query query = hibernateSession.createQuery(queryInfo.getQueryString());
		DisplayPage page = new DisplayPage(pageSize, pageNumber);
		String countStr = "select count(*) " + query.getQueryString();
		Query countQuery = hibernateSession.createQuery(countStr);
		if (queryInfo.getQueryParameters() != null) {
			for (int i = 0; i < queryInfo.getQueryParameters().size(); i++) {
				log.debug("queryPara[" + i + "]=" + queryInfo.getQueryParameters().get(i));
				query.setParameter(i, queryInfo.getQueryParameters().get(i));
				countQuery.setParameter(i, queryInfo.getQueryParameters().get(i));
			}
		}
		// query.
		page.setFullListSize(((Integer) countQuery.uniqueResult()).intValue());
		int startRow = (pageNumber - 1) * page.getObjectsPerPage();
		List list = query.setFirstResult(startRow).setMaxResults(page.getObjectsPerPage()).list();
		log.debug("\n*******\n* getDisplayPage List=" + list.size());

		page.setList(list);
		page.setSearchId(countStr);
		// query.
		return page;
	}

	public static Query getQuery(String queryString, List setList) {
		log.debug("[getQuery] queryString=" + queryString);
		Session hibernateSession = HibernateSessionFactory.getSession();
		Query query = hibernateSession.createQuery(queryString);
		String test = "";
		if (setList != null && setList.size() > 0) {
			for (int i = 0; i < setList.size(); i++) {
				test += "," + i + "=" + setList.get(i);
				query.setParameter(i, setList.get(i));
				// addQueryParam(query, i,setList.get(i));
			}
		}
		log.debug("[getQuery] query=" + queryString + "\nset:: " + test);
		return query;
	}

	private static void addQueryParam(Query query, int index, Object o) {
		if (o instanceof String) {
			query.setString(index, (String) o);
			return;
		}
		if (o instanceof Date) {
			query.setDate(index, (Date) o);
			return;
		}
		if (o instanceof Integer) {
			query.setInteger(index, ((Integer) o).intValue());
			return;
		}
		if (o instanceof Double) {
			query.setDouble(index, ((Double) o).doubleValue());
			return;
		}
		if (o instanceof Long) {
			query.setLong(index, ((Long) o).longValue());
			return;
		}
		if (o instanceof String) {
			query.setString(index, (String) o);
			return;
		}
	}

	/**
	 * @param args
	 * @throws BusinessException 
	 */
	public static void main(String[] args) throws BusinessException {
		//      分页查询测试
	    	PropertyCondition[] pConditions = new PropertyCondition[]{
	    			 //   			new PropertyCondition("ordering",new Integer(6),PropertyCondition.OPERATOR_LT),
	    			 //    			new PropertyCondition("username","%2",PropertyCondition.OPERATOR_LIKE)
	    	};
	    	CriteriaInfo cinfo = new CriteriaInfo(User.class, pConditions, Order.asc("lastupdatedby"));
	    	DisplayPage page = PageManager.getDisplayPage(3, 1, cinfo);
	    	System.out.println("    Result FullListSize="+page.getFullListSize());
	   		 System.out.println("page.getList().size()="+page.getList().size());

	}

}
